package com.itheima.filter;

import com.itheima.utils.CurrentHolder;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {

    /*
        //初始化方法 , web服务器启动的时候执行 , 只执行一次
        @Override
        public  void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    */

    //拦截到请求之后执行 , 会执行多次
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1. 获取到请求路径 url , httpServletRequest
        String url = request.getRequestURI();//

        //2. 判断是否是登录请求 , 如果路径中 url包含 /login , 说明是登陆操作 , 放行.
        if (url.toString().contains("login")) {
            filterChain.doFilter(request, response);
            return;
        }

        //3. 获取请求头中的 JWT令牌(token)
        String token = request.getHeader("token");

        //4. 判断令牌 token是否存在 , 如果不存在 , 说明用户没有登陆 , 返回错误信息(响应401状态码)
        if (token == null || token.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);//401
            return;//不能忘!!!!!!!

        }

        //5. 如果令牌 token 存在 , 校验令牌 , 如果校验失败 -> 返回错误信息 (响应401状态码)
        try {
            Claims claims = JwtUtils.parseJWT(token);
            Integer empId = Integer.valueOf(claims.get("id").toString());
            CurrentHolder.setCurrentId(empId);//存入
            log.info("当前登录员工ID:{},将其存入ThreadLocal", empId);
        } catch (Exception e) {
            response.setStatus(401);//401
            return;
        }

        //6. 校验通过 , 放行
        log.info("令牌合法 , 放行");
        filterChain.doFilter(request, response);

        //7. 删除ThreadLocal中的数据
        CurrentHolder.remove();
    }

    /*
        //销毁方法 , web服务器关闭的时候执行 , 只执行一次
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    */
}
